package com.oanda.blackberry.view;

import com.oanda.blackberry.restapi.Account;
import com.oanda.blackberry.restapi.AccountEntry;
import com.oanda.blackberry.restapi.AccountStatus;
import com.oanda.blackberry.restapi.User;
import com.oanda.blackberry.ui.ColoredLabelField;
import com.oanda.blackberry.ui.OandaMainScreen;
import com.oanda.blackberry.util.AbstractController;
import com.oanda.blackberry.util.AbstractViewPanel;
import com.oanda.blackberry.util.DefaultController;
import com.oanda.blackberry.util.Model;
import com.oanda.blackberry.util.PropertyChangeEvent;
import com.oanda.blackberry.util.Settings;
import com.oanda.blackberry.util.log.Logger;
import net.rim.device.api.system.Application;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.Screen;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BasicEditField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.ListField;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.RadioButtonField;
import net.rim.device.api.ui.component.RadioButtonGroup;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.decor.BackgroundFactory;

public class AccountsView extends OandaMainScreen implements AbstractViewPanel {
	DefaultController controller;
	RadioButtonGroup group = new RadioButtonGroup();

	VerticalFieldManager groupManager = new VerticalFieldManager();

	VerticalFieldManager signleAccountStatusManager = new VerticalFieldManager();

	ButtonField useIt = new ButtonField("Use this Account", 65536L);

	ColoredLabelField activeAccountDetailsLabel = new ColoredLabelField(
			9055202, "Active account details", 36028797018963968L);
	BasicEditField accountName = new BasicEditField("Account Name: ", "");
	BasicEditField accountId = new BasicEditField("Account Number: ", "");
	BasicEditField accountBalance = new BasicEditField("Account Balance: ", "");
	BasicEditField accountCurrency = new BasicEditField("Currency: ", "");
	AccountStatus tempStatus;
	boolean active = false;
	private static AccountsView instance;
	AccountListField list;
	VerticalFieldManager listManager = new VerticalFieldManager();

	MenuItem showAccountStatusMenuItem = new MenuItem("Show Account Status", 1,
			1) {
		public void run() {
			AccountsView.this.showAccountStatus();
		}
	};

	boolean shownWarning = false;

	boolean accountDetailsMenuPressed = false;
	MenuItem accountStatus = new MenuItem("Account Details", 10, 1000) {
		public void run() {
			if ((AccountsView.this.list != null)
					&& (AccountsView.this.list.getList() != null)
					&& (AccountsView.this.list.getList().getSelectedIndex() > -1)
					&& (Model.getModel().getAccount() != null)
					&& (Model.getModel().getAccount().getAccountEntrys() != null)
					&& (AccountsView.this.list.getList().getSelectedIndex() < Model
							.getModel().getAccount().getAccountEntrys().length)) {
				AccountsView.this.accountDetailsMenuPressed = true;
			}
			AccountsView.this.controller.accountStatus(Model.getModel()
					.getAccount().getAccountEntrys()[AccountsView.this.list
					.getList().getSelectedIndex()].getId(), Model.getModel()
					.getSessionToken());
		}
	};

	MenuItem exitMenuItem = new MenuItem("Back", 10, 1001) {
		public void run() {
			AccountsView.this.controller.popScreen(AccountsView.instance);
		}
	};

	public AccountsView(DefaultController controller) {
		this.controller = controller;
		getMainManager().setBackground(
				BackgroundFactory.createSolidBackground(4473924));
		instance = this;

		updateTitle("Accounts");
		addMenuItem(this.showAccountStatusMenuItem);

		add(this.listManager);
	}

	private void removeActiveAccountDetails() {
	}

	private void setActiveAccountDetails(final AccountStatus status) {
		if (status != null)
			UiApplication.getUiApplication().invokeLater(new Runnable() {
				private final AccountStatus _status = status;

				public void run() {
					AccountsView.this.accountBalance.setText(String
							.valueOf(this._status.getBalance()));
					AccountsView.this.accountId.setText(this._status.getId());
					AccountsView.this.accountCurrency.setText(Model.getModel()
							.getActiveAccountEntry().getHomecurr());
					AccountsView.this.accountName.setText(Model.getModel()
							.getActiveAccountEntry().getName());

					AccountsView.this.setSelectedIndex(this._status.getId());
				}
			});
	}

	private void setSelectedIndex(String accountId) {
		Logger.log("setSelectedIndex( group size: "
				+ String.valueOf(this.group.getSize()) + ")" + "accointId: "
				+ accountId);

		if (accountId != null) {
			if ((this.groupManager.getFieldCount() > 1) && (accountId != null)) {
				Logger.log("setSelectedIndex( group size: "
						+ String.valueOf(this.group.getSize())
						+ " groupManager.getFieldCount()"
						+ this.groupManager.getFieldCount() + ")");

				for (int i = 0; i < this.groupManager.getFieldCount(); i++) {
					RadioButtonField f = (RadioButtonField) this.groupManager
							.getField(i);
					if ((f.getLabel() != null)
							&& (f.getLabel().indexOf(accountId) > -1)
							&& (f.getLabel().indexOf("(A) ") < 0)) {
						if (i < this.group.getSize()) {
							this.group.setSelectedIndex(i);
							f.setLabel("(A) " + f.getLabel());
						} else {
							Logger.log("setting invalid index("
									+ String.valueOf(i) + " group size: "
									+ String.valueOf(this.group.getSize())
									+ ")");
						}

					} else if (f.getLabel().startsWith("(A) "))
						f.setLabel(f.getLabel().substring(4));
				}
			}
		}
	}

	private void showAccountStatus() {
		if (this.group.getSelectedIndex() != -1)
			this.controller.accountStatus(Model.getModel().getAccount()
					.getAccountEntrys()[this.group.getSelectedIndex()].getId(),
					Model.getModel().getSessionToken());
	}

	private void setActiveAccount(String accountId) {
		Logger.log("set active account: " + accountId);
		if (accountId == null)
			return;

		if ((this.group != null) && (this.group.getSize() > 1)) {
			removeActiveAccountDetails();
			setActiveAccountDetails(this.tempStatus);
			this.active = true;
		} else {
			this.active = true;
		}
	}

	private void setAcountStatus(AccountStatus account) {
		this.tempStatus = account;
		if (Model.getModel().getAccount().getAccountEntrys().length == 1) {
			Logger.log("ACCOUNT LEN == 1!");

			if (UiApplication.getUiApplication().getActiveScreen().equals(this)) {
				this.controller.popScreen(this);

				this.controller.propertyChange(new PropertyChangeEvent(null,
						"requestShowAccountDetailsView", null, account));
			}
		} else {
			if (this.list != null) {
				this.list.setAccountStatus(account);
			}

			if (this.accountDetailsMenuPressed) {
				this.accountDetailsMenuPressed = false;
				this.controller.propertyChange(new PropertyChangeEvent(null,
						"requestShowAccountDetailsView", null, account));
			}
		}
	}

	private void setAccountEnties(final AccountEntry[] entries) {
		Runnable runnable = new Runnable() {
			private final AccountEntry[] _entries = entries;

			public void run() {
				if ((this._entries != null) && (this._entries.length > 1)) {
					AccountsView.this.list = null;
					AccountsView.this.listManager.deleteAll();
					AccountsView.this.autosetActiveAccount(this._entries);
					AccountsView.this.list = new AccountListField(
							this._entries);
					AccountsView.this.listManager.add(AccountsView.this.list
							.getList());

					AccountsView.this.updateAccountStatus(this._entries);
					AccountsView.this.hideThrobber();

					return;
				}
			}
		};
		UiApplication.getUiApplication().invokeLater(runnable);
	}

	protected void onUiEngineAttached(boolean attached) {
		if (attached) {
			Logger.log("AccountsView onUiEngineAttached true");
			super.onUiEngineAttached(attached);

			this.controller.accountList(Model.getModel().getSessionToken(),
					Model.getModel().getUser().getUsername());
		}
	}

	public void modelPropertyChange(PropertyChangeEvent evt) {
		if ((evt.getPropertyName() != null)
				&& (evt.getPropertyName().equals("setErrorMessage"))) {
			hideThrobber();
			if ((evt.getNewValue() != null)
					&& ((evt.getNewValue() instanceof String))) {
				diplayError((String) evt.getNewValue(), 3000);
			}
		}
		if ((evt.getPropertyName() != null)
				&& (evt.getPropertyName().equals("setStatusMessage"))) {
			if ((evt.getNewValue() != null)
					&& ((evt.getNewValue() instanceof String))) {
				String s = (String) evt.getNewValue();
				if ((s != null) && (s.length() > 0))
					setStatusField(s);
				else {
					removeStatusField();
				}
			}
		} else if ((evt.getPropertyName() != null)
				&& (evt.getPropertyName().equals("setSettings"))) {
			Settings s = (Settings) evt.getNewValue();
			if ((s == null) || (s.getAccount() == null)
					|| (s.getAccount().getAccountEntrys() == null))
				;
		} else if ((evt.getPropertyName() != null)
				&& (evt.getPropertyName().equals("setActiveAccount"))) {
			setActiveAccount((String) evt.getNewValue());
		} else if ((evt.getPropertyName() != null)
				&& (evt.getPropertyName().equals("setAccountStatus"))) {
			Logger.log("SetAccountStatus");
			if ((evt.getNewValue() != null)
					&& ((evt.getNewValue() instanceof AccountStatus)))
				setAcountStatus((AccountStatus) evt.getNewValue());
		} else if ((evt.getPropertyName() == null)
				|| (!evt.getPropertyName().equals("sessionToken"))) {
			if ((evt.getPropertyName() != null)
					&& (evt.getPropertyName().equals("setAccount"))) {
				Account a = (Account) evt.getNewValue();

				if (a != null) {
					Logger.log("Accounts View: setAccount 0 "
							+ a.getAccountEntrys()[0].getId() + " "
							+ a.getAccountEntrys()[0].getName());

					if (a.getAccountEntrys().length > 1) {
						setAccountEnties(a.getAccountEntrys());
					} else if (a.getAccountEntrys().length == 1) {
						setAccountEnties(a.getAccountEntrys());

						showThrobberPlain();

						this.controller.useAccount(a.getAccountEntrys()[0]
								.getId());

						this.controller.accountStatus(a.getAccountEntrys()[0]
								.getId(), Model.getModel().getSessionToken());
					}

				}

			} else if ((evt.getPropertyName() != null)
					&& (evt.getPropertyName().equals("hideAccountsView"))) {
				onClose();
			} else if ((evt.getPropertyName() != null)
					&& (evt.getPropertyName().equals("requestShowAccountsView"))) {
				this.controller.pushScreen(this);
			}
		}
	}

	public boolean onClose() {
		if (this.active) {
			this.controller.popScreen(this);
			this.controller.propertyChange(new PropertyChangeEvent(this,
					"onCloseAccountsView", this.controller, this.controller));
		} else if (this.group.getSize() > 1) {
			if (!this.shownWarning) {
				this.shownWarning = true;
				DefaultController.inform("Please select active account");
				return false;
			}
			this.shownWarning = false;
			this.controller.popScreen(this);
			return true;
		}

		this.controller.popScreen(this);
		return true;
	}

	protected void makeMenu(Menu menu, int instance) {
		if ((Model.getModel().getAccount() != null)
				&& (Model.getModel().getAccount().getAccountEntrys() != null)
				&& (Model.getModel().getAccount().getAccountEntrys().length > 1)) {
			menu.add(this.accountStatus);
		}

		menu.add(this.exitMenuItem);
	}

	private void updateAccountStatus(AccountEntry[] entry) {
		if ((entry != null) && (entry.length > 1))
			for (int i = 0; i < entry.length; i++)
				this.controller.accountStatus(entry[i].getId(), Model
						.getModel().getSessionToken());
	}

	private void autosetActiveAccount(AccountEntry[] accounts) {
		if ((accounts != null) && (accounts.length > 0))
			if (accounts.length == 1) {
				accounts[0].setActive(true);

				this.controller.propertyChange(new PropertyChangeEvent(null,
						"setActiveAccount", null, accounts[0].getId()));
			} else {
				boolean hasActive = false;
				int primaryIndex = 0;
				for (int i = 0; i < accounts.length; i++) {
					if (accounts[i].getActive()) {
						hasActive = true;
					}
					if (accounts[i].getName().equalsIgnoreCase("primary")) {
						primaryIndex = i;
					}
				}
				if (!hasActive) {
					accounts[primaryIndex].setActive(true);

					this.controller.propertyChange(new PropertyChangeEvent(
							null, "setActiveAccount", null,
							accounts[primaryIndex].getId()));
				}
			}
	}
}
